package app

import (
	"gitee.com/vrv_media/go-micro-framework/registry"
	"gitee.com/vrv_media/go-micro-framework/server"
	"github.com/google/uuid"
	"net/url"
	"os"
	"syscall"
	"time"
)

type Option func(o *Options)

type Options struct {
	id        string
	name      string
	endpoints []*url.URL

	sigs []os.Signal

	// registrar 允许用户传入自己的注册 实现
	registrar registry.Registrar
	// startTimeout 启动服务超时时间
	startTimeout time.Duration
	// registrarTimeout 注册超时退出
	registrarTimeout time.Duration
	// stopTimeout 注销超时退出
	stopTimeout time.Duration
	servers     []server.Server
	tags        []string
}

func DefaultOptions() *Options {
	o := &Options{
		sigs:             []os.Signal{syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT},
		startTimeout:     5 * time.Minute,  // 启动服务的时间，放大一点，否则无法监听到服务启动失败
		registrarTimeout: 10 * time.Second, // 注册服务 超时时间
		stopTimeout:      10 * time.Second, // 注销服务 超时时间
	}
	if id, err := uuid.NewUUID(); err == nil {
		o.id = id.String()
	}
	return o
}

func WithTags(tags ...string) Option {
	return func(o *Options) {
		o.tags = append(o.tags, tags...)
	}
}
func WithStartTimeout(timeout time.Duration) Option {
	return func(o *Options) {
		o.startTimeout = timeout
	}
}
func WithRegistrarTimeout(timeout time.Duration) Option {
	return func(o *Options) {
		o.registrarTimeout = timeout
	}
}
func WithStopTimeout(timeout time.Duration) Option {
	return func(o *Options) {
		o.stopTimeout = timeout
	}
}
func WithID(id string) Option {
	return func(o *Options) {
		o.id = id
	}
}
func WithName(name string) Option {
	return func(o *Options) {
		o.name = name
	}
}
func WithEndpoints(endpoints []*url.URL) Option {
	return func(o *Options) {
		o.endpoints = endpoints
	}
}
func WithSigs(sigs []os.Signal) Option {
	return func(o *Options) {
		o.sigs = sigs
	}
}
func AddSigs(sigs ...os.Signal) Option {
	return func(o *Options) {
		if len(sigs) == 0 {
			return
		}
		o.sigs = append(o.sigs, sigs...)
	}
}

func WithServer(srvs ...server.Server) Option {
	return func(o *Options) {
		o.servers = srvs
	}
}
func AddServer(srvs ...server.Server) Option {
	return func(o *Options) {
		if len(srvs) == 0 {
			return
		}
		o.servers = append(o.servers, srvs...)
	}
}

func WithRegistrar(registrar registry.Registrar) Option {
	return func(o *Options) {
		o.registrar = registrar
	}
}
